/*
 * Created on 12-ago-2005
 *
 * To change the template for this generated file go to
 * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
 */
package org.mushroomdb.engine.statistics;

import org.mushroomdb.catalog.Catalog;
import org.mushroomdb.catalog.CatalogHelper;
import org.mushroomdb.catalog.Column;
import org.mushroomdb.catalog.Register;
import org.mushroomdb.catalog.Table;
import org.mushroomdb.engine.EvaluationEngineFactory;
import org.mushroomdb.engine.ResultSet;
import org.mushroomdb.exception.EvaluationEngineException;
import org.mushroomdb.exception.RDBMSRuntimeException;
import org.mushroomdb.query.Criteria;
import org.mushroomdb.query.impl.SelectionQuery;


public class StatisticsRetriever {
	private static StatisticsRetriever instanceReference;
	
	public static StatisticsRetriever getInstance() {
		if (StatisticsRetriever.instanceReference == null) StatisticsRetriever.instanceReference = new StatisticsRetriever();
		return StatisticsRetriever.instanceReference;
	}
	
	private StatisticsRetriever() {
		
	}
	
	public long getRegisterCount(Table table) {
		return this.getRegisterCountEstimation(table.getName());
	}
	
	public long getPageCount(Table table) {
		return this.getPageCountEstimation(table.getName());
	}
	
	public int getRegisterSize(Table table) {
		return this.getRegisterSize(table.getName());
	}
	
	private long getRegisterCountEstimation(String name) throws RDBMSRuntimeException {
		Table sysTableTable = Catalog.getInstance().getTableByName(CatalogHelper.SYS_TABLE_TABLE_NAME);
		
		Column registerCountColumn = sysTableTable.getColumn(CatalogHelper.ST_REGISTER_COUNT_COLUMN_NAME);
		Column nameColumn = sysTableTable.getColumn(CatalogHelper.ST_NAME_COLUMN_NAME);
				
		SelectionQuery registerCountRetrievalQuery = new SelectionQuery();
		Criteria registerCountRetrievalCriteria = registerCountRetrievalQuery.getNewCriteria();
		registerCountRetrievalCriteria.addEqualsTo(nameColumn, name);
		//registerCountRetrievalQuery.getMainCriteria().addAndCriteria(registerCountRetrievalCriteria);
		
		registerCountRetrievalQuery.addProjection(registerCountColumn);
		
		ResultSet registerCountResultSet = EvaluationEngineFactory.getInstance().executeUnalterableQuery(registerCountRetrievalQuery);
		
		long registerCount;
		
		try {
			if (registerCountResultSet.hasNext()) {
				Register register = (Register) registerCountResultSet.next();
				registerCount = ((Long)( register ).getValue(1)  ).longValue();
			}
			else throw new EvaluationEngineException("Malformed catalog statistics.");
		} catch (EvaluationEngineException e) {
			throw new RDBMSRuntimeException(e);
		} finally {
			registerCountResultSet.close();
		}
		return registerCount;
	}
	
	private long getPageCountEstimation(String name) throws RDBMSRuntimeException {
		Table sysTableTable = Catalog.getInstance().getTableByName(CatalogHelper.SYS_TABLE_TABLE_NAME);
		
		Column pageCountColumn = sysTableTable.getColumn(CatalogHelper.ST_PAGE_COUNT_COLUMN_NAME);
		Column nameColumn = sysTableTable.getColumn(CatalogHelper.ST_NAME_COLUMN_NAME);
				
		SelectionQuery pageCountRetrievalQuery = new SelectionQuery();
		Criteria registerCountRetrievalCriteria = pageCountRetrievalQuery.getNewCriteria();
		registerCountRetrievalCriteria.addEqualsTo(nameColumn, name);
		//registerCountRetrievalQuery.getMainCriteria().addAndCriteria(registerCountRetrievalCriteria);
		
		pageCountRetrievalQuery.addProjection(pageCountColumn);
		
		ResultSet pageCountResultSet = EvaluationEngineFactory.getInstance().executeUnalterableQuery(pageCountRetrievalQuery);
		
		long pageCount;
		
		try {
			if (pageCountResultSet.hasNext()) {
				Register register = (Register) pageCountResultSet.next();
				pageCount = ((Long)( register ).getValue(1)  ).longValue();
			}
			else throw new EvaluationEngineException("Malformed catalog statistics.");
		} catch (EvaluationEngineException e) {
			throw new RDBMSRuntimeException(e);
		} finally {
			pageCountResultSet.close();
		}
		return pageCount;
	}
	
	private int getRegisterSize(String name) throws RDBMSRuntimeException {
		Table sysTableTable = Catalog.getInstance().getTableByName(CatalogHelper.SYS_TABLE_TABLE_NAME);
		Table sysColumnTable = Catalog.getInstance().getTableByName(CatalogHelper.SYS_COLUMN_TABLE_NAME);
	
		Column nameColumn = sysTableTable.getColumn(CatalogHelper.ST_NAME_COLUMN_NAME);
		Column sizeColumn = sysColumnTable.getColumn(CatalogHelper.SC_SIZE_COLUMN_NAME);
		Column idTableColumn = sysColumnTable.getColumn(CatalogHelper.SC_ID_TABLE_COLUMN_NAME);
		
		Column idColumn = sysTableTable.getColumn(CatalogHelper.ST_ID_COLUMN_NAME);
		
		SelectionQuery columnSizesRetrievalQuery = new SelectionQuery();
		columnSizesRetrievalQuery.getMainCriteria().addEqualsTo(idTableColumn, idColumn);
		columnSizesRetrievalQuery.getMainCriteria().addEqualsTo(nameColumn, name);
		//Criteria fkCriteria = columnSizesRetrievalQuery.getNewCriteria();
		//Criteria nameCriteria = columnSizesRetrievalQuery.getNewCriteria();
		
		//fkCriteria.addEqualsTo(idTableColumn, idColumn);
		//nameCriteria.addEqualsTo(nameColumn, name);
		
		//columnSizesRetrievalQuery.getMainCriteria().addAndCriteria(fkCriteria);
		//columnSizesRetrievalQuery.getMainCriteria().addAndCriteria(nameCriteria);
		
		columnSizesRetrievalQuery.addProjection(sizeColumn);
		
		ResultSet columnSizesResultSet = EvaluationEngineFactory.getInstance().executeUnalterableQuery(columnSizesRetrievalQuery);
		int registerSize = 0;
		try {
			while (columnSizesResultSet.hasNext()) {
				registerSize += ( (Integer) ( (Register) columnSizesResultSet.next() ).getValue(1)  ).intValue();
			}
		} catch (EvaluationEngineException e) {
			throw new RDBMSRuntimeException(e);
		} finally {
			columnSizesResultSet.close();
		}
		return registerSize;
	}
	
}
